package com.gsafety.library.Net;

import com.gsafety.library.Net.RetrofitExt.factorys.GsonConverterFactory;
import com.gsafety.library.Net.RetrofitExt.factorys.LiveDataCallAdapterFactory;
import com.gsafety.library.Net.okhttputil.Cookie.CookieJar;
import com.gsafety.library.Net.okhttputil.interceptor.NetInterceptor;
import com.gsafety.library.Utils.Log;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * 网络框架的核心所在
 */
public class BaseNetCore {
    //存放网络设置的map
    private HashMap<String, NetProvider> providerMap = new HashMap();
    //存放retrofit的map
    private HashMap<String, Retrofit> retrofitMap = new HashMap();
    //存放okhttp的map
    private HashMap<String, OkHttpClient> clientMap = new HashMap();

    private static final long connectTimeoutMills = 10 * 1000L;
    private static final long readTimeoutMills = 10 * 1000L;

    NetProvider commonProvider = null;
    private GsonConverterFactory gsonFactory = GsonConverterFactory.create();
    private static BaseNetCore INSTANCE;


    //方法同步，调用效率低
    public static BaseNetCore getInstance(){
        if(INSTANCE==null){
            INSTANCE=new BaseNetCore();
        }
        return INSTANCE;
    }
    /**
     * 获取retrofit实例
     */
   public Retrofit getRetrofit(String baseUrl, NetProvider netProvider) {
        NetProvider provider = netProvider;
        if (empty(baseUrl)) {
            throw new IllegalStateException("baseUrl can not be null");
        }
        if (retrofitMap.get(baseUrl) != null) {
            return retrofitMap.get(baseUrl);
        }

        if (provider == null) {
            provider = providerMap.get(baseUrl);
            if (provider == null) {
                provider = commonProvider;
            }
        }

        checkProvider(provider);
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(baseUrl)
                //首先判断是否需要转换成字符串，简单类型
                .addConverterFactory(ScalarsConverterFactory.create())
                //再将转换成bean
                .addConverterFactory(gsonFactory)
                .addCallAdapterFactory(new LiveDataCallAdapterFactory())
                .client(getClient(baseUrl, provider));
        Retrofit retrofit = builder.build();
        retrofitMap.put(baseUrl,retrofit);
        providerMap.put(baseUrl, provider);
        return retrofit;
    }

    /**
     * 获取OkHttpClient实例
     */
    private OkHttpClient getClient(String baseUrl, NetProvider provider) {
        if (empty(baseUrl)) {
            throw new IllegalStateException("baseUrl can not be null");
        }

        if (clientMap.get(baseUrl) != null) {
            return clientMap.get(baseUrl);
        }

        checkProvider(provider);

        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (provider.getSSLSocketFactory() != null){
            builder.sslSocketFactory(provider.getSSLSocketFactory());
        }
        if (provider.getHostnameVerifier() != null){
            builder.hostnameVerifier(provider.getHostnameVerifier());
        }
        if (provider.configConnectTimeoutSecs() != 0L){
            builder.connectTimeout( provider.configConnectTimeoutSecs(),TimeUnit.SECONDS);
        }else {
            builder.connectTimeout(connectTimeoutMills,TimeUnit.SECONDS);
        }
        if(provider.configReadTimeoutSecs() != 0L){
            builder.readTimeout(provider.configReadTimeoutSecs(),TimeUnit.SECONDS);
        }else {
            builder.readTimeout( readTimeoutMills,TimeUnit.SECONDS);
        }
        if(provider.configWriteTimeoutSecs() != 0L){
            builder.writeTimeout(provider.configWriteTimeoutSecs(),TimeUnit.SECONDS);
        }else{
            builder.writeTimeout(readTimeoutMills,TimeUnit.SECONDS);
        }
        CookieJar cookieJar = provider.configCookie();
        if (cookieJar != null) {
            builder.cookieJar(cookieJar);
        }

        provider.configHttps(builder);

        RequestHandler handler = provider.configHandler();
        builder.addInterceptor(new NetInterceptor(handler));

        ArrayList<Interceptor> interceptors = provider.configInterceptors();
        if (!empty(interceptors)) {
            for(Interceptor it:interceptors){
                builder.addInterceptor(it);
            }
        }
        if (provider.configLogEnable()) {
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger(){

                @Override
                public void log(@NotNull String s) {
                    Log.d("request:===",s + "");
                }
            });
            loggingInterceptor.level(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(loggingInterceptor);
        }
        OkHttpClient client = builder.build();
        clientMap.put(baseUrl,client);
        providerMap.put(baseUrl,provider);
        return client;
    }

class k implements HttpLoggingInterceptor.Logger{

    @Override
    public void log(@NotNull String s) {

    }
}
    /**
     * 判断baseUrl是否为空
     */
    private Boolean empty(String baseUrl) {
        return baseUrl == null || baseUrl.isEmpty();
    }

    /**
     * 判断拦截器是否为空
     */
    private Boolean empty(ArrayList<Interceptor> interceptors) {
        return interceptors == null || interceptors.isEmpty();
    }

    /**
     * 判断是否有拦截器
     */
    private void checkProvider(NetProvider provider) {
        if (provider == null) {
            throw new IllegalStateException("must register provider first");
        }
    }

    /**
     * 获取retrofit实例的map集合
     */
    Map<String, Retrofit> getRetrofitMap() {
        return retrofitMap;
    }

    /**
     * 获取OkHttpClient实例的map集合
     */
    Map<String, OkHttpClient> getClientMap() {
        return clientMap;
    }

    /**
     * 注册网络请求拦截器
     */
    void registerProvider(NetProvider provider) {
        commonProvider = provider;
    }

    /**
     * 注册网络请求拦截器
     */
    void registerProvider(String baseUrl, NetProvider provider) {
        providerMap.put(baseUrl, provider);
    }

    /**
     * 清除map集合
     */
    void clearCache() {
        retrofitMap.clear();
        clientMap.clear();
    }

    public GsonConverterFactory getGsonFactory() {
        return gsonFactory;
    }
}
